package cleanstarxchange.server;

import java.util.ArrayList;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Stock  implements Comparable<Stock>
{
	// Primary Key
	// ID of celebrity
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;
    // Field will be stored in datastore
    // Name of celebrity
	@Persistent 
	private String name;
	// Field will be stored in datastore
	// Symbol for the stock
	@Persistent 
	private String symbol;	
	// Field will be stored in datastore
	// List of prevoius prices, will only store previous 50 prices
	@Persistent 
	private ArrayList<Double> priceList;
	// Field will be stored in datastore
	// Current price of stock
	@Persistent 
	private double currentPrice;
	// Field will be stored in datastore
	// High price for stock
	@Persistent 
	private double high;
	// Field will be stored in datastore
	// Low price for stock
	@Persistent 
	private double low;
	
	/**
	 * 
	 * @param name - name of the celebrity
	 * @param symbol - symbol for stock
	 * @param id - primary key of stock
	 * @param currentPrice - current price of stock
	 * @param priceList - list of previous prices
	 */
	public Stock( String name, String symbol, Long id, double currentPrice, ArrayList<Double> priceList )
	{
		this.name = name;
		this.symbol = symbol;
		this.id = id;
		this.currentPrice = currentPrice;
		this.high = currentPrice;
		this.low = currentPrice;
		this.setPriceList(priceList);
		this.getPriceList().add(currentPrice);
	}
	
	/**
	 * Get the celebrity name of the stock
	 * @return - celebrity name of stock
	 */
	public String getName()
	{
		return name;
	}
	
	/**
	 * Get the symbol of the stock
	 * @return - symbol of stock
	 */
	public String getSymbol()
	{
		return symbol;
	}
	
	/**
	 * Get the ID (primary key) of the stock
	 * @return - ID of stock
	 */
	public Long getStockID()
	{
		return id;
	}
	
	/**
	 * Get current price of stock
	 * @return - current price of stock
	 */
	public double getCurrentPrice()
	{
		return currentPrice;
	}
	
	/**
	 * Get starting price of stock
	 * @return - starting price of stock
	 */
	public double getInitialPrice()
	{
		return getPriceList().get(0);
	}
	
	/**
	 * Get the price of stock from the past
	 * @param intervalsBack - number of intervals in the past, must be < 50 since priceList only stores 50 prices
	 * @return - price of stock at that time interval
	 */
	public double getPreviousPrice( int intervalsBack )
	{
		return getPriceList().get(getPriceList().size() - intervalsBack - 1);
	}	
	
	/**
	 * Retrieves the previous prices in a string
	 * @return - previous prices of stock
	 */
	public String getStringPrices()
	{
		// Iterates through array list to retrieve prices and put into string
		String stringPrices = getPriceList().get(0).toString();
		for(int i=1; i<getPriceList().size(); i++)
		{
			stringPrices += "," + getPriceList().get(i).toString();
		}
		return stringPrices;
	}
	
	/**
	 * Creates string containing address to graph image.
	 * @return - String containing address to graph image.
	 */
	public String getGraph()
	{		
		double gridValue = (100/(this.getHighPrice())) * 10;
		// Creates a string containing address to graph image.
		String graphImage = "http://chart.apis.google.com/chart?"
		+ "chtt=Stock+History&"
		+ "cht=lc&chs=500x300&chd=t:"
		+ getStringPrices() + "&"
		+ "chxr=1,0," + this.getHighPrice() + "&chds=0," + this.getHighPrice() + "&"
		+ "chco=4d89f9&"
		+ "chxt=x,y&chxl=0:|&"
		+ "chls=3,1,0&"
		+ "chg=0," + gridValue + ",5,5";
		
		return graphImage;
		}
		
	
	/**
	 * Update the price of the stock
	 * @param newPrice - new price of the stock ( must be > 0
	 */
	public void updatePrice( double newPrice )
	{
		// if price list has 50 elements, remove oldest one to make room for new one
		// only store 50 previous prices
		if (priceList.size() == 50)
			priceList.remove(0);
		
		// check if new prices being added will be high price
		if ( newPrice > high )
			high = newPrice;
		// check if new price being added will be low price
		else if ( newPrice < low )
			low = newPrice;
		
		// set current price as the new price
		currentPrice = newPrice;
		
		// add new price into the price list
		getPriceList().add( newPrice );
	}
	
	/**
	 * Get the high price of the stock
	 * @return - high price
	 */
	public double getHighPrice()
	{
		return high;
	}
	
	/**
	 * Get the low price of the stock
	 * @return - low price
	 */
	public double getLowPrice()
	{
		return low;
	}

	@Override
	/**
	 * Compare stocks based on how much the stock as gone up/down within previous 5 intervals
	 * @param stock - stock to compare current stock to
	 * @return - 0 if stocks are equal, -1 if current stock has higher gain, 1 if current stock has lower gain
	 */
	public int compareTo(Stock stock) 
	{
		// up or down of current stock
		double gain1 = ((currentPrice-getPreviousPrice(5))/getPreviousPrice(5))*100;
		// up or down of stock to compare
		double gain2 = ((stock.getCurrentPrice()-stock.getPreviousPrice(5))/stock.getPreviousPrice(5))*100;
		if ( gain1 == gain2 )
			return 0;
		else if ( gain1 > gain2 )
			return -1;
		else 
			return 1;
	}

	/**
	 * Give a new price list to the stock
	 * @param priceList - new price list
	 */
	public void setPriceList(ArrayList<Double> priceList) {
		this.priceList = priceList;
	}

	/**
	 * Get price list of stock
	 * @return - price list
	 */
	public ArrayList<Double> getPriceList() {
		return priceList;
	}
}

